
package com.tspp.dao;

import com.tspp.common.ResourceManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Abstract class that has realization of commom methods for all DAO classes
 * Method getDtoFrom(ResultSet rs) is abstract, because dto is specific for every table
 * @author Maks
 */
public abstract class AbstractDao<T> {

    /**
     * Return newly created data transfer object
     * @param rs ResultSet which contains data
     * @return data transfer object of specified tablw
     * @throws SQLException
     */
    abstract protected T getDtoFrom(ResultSet rs) throws SQLException;

    /**
     * Create an arraylist from data transfer objects
     * @param rs ResultSet which contains data
     * @return arrayList of datatransfer objects
     * @throws SQLException
     */
    protected List<T> fetchMultiResults(ResultSet rs) throws SQLException {
        List<T> resultList = new ArrayList<T>();
        while (rs.next()) {
            T dto = getDtoFrom(rs);
            resultList.add(dto);
        }
        return resultList;
    }

    /**
     * Select records from tsble specified by sql string
     * @param sql query string
     * @param sqlParams parametres of query
     * @return arrayList of datatransfer objects
     * @throws DaoException
     */
    protected List<T> findByDynamicSelect(String sql, Object[] sqlParams) throws DaoException {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            conn = ResourceManager.getConnection();
            //System.out.println("Executing " + SQL);
            // prepare statement
            stmt = conn.prepareStatement(sql);
            // bind parameters
            for (int i = 0; sqlParams != null && i < sqlParams.length; i++) {
                stmt.setObject(i + 1, sqlParams[i]);
            }
            rs = stmt.executeQuery();
            // fetch the results
            return fetchMultiResults(rs);
        } catch (Exception _e) {
            throw new DaoException("Exception: " + _e.getMessage(), _e);
        } finally {
            ResourceManager.close(rs);
            ResourceManager.close(stmt);
            ResourceManager.close(conn);
        }
    }
}

